/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package server;

import commom.Network;
import commom.VirtualMachine;
import java.util.ArrayList;
import java.util.Scanner;
import java.util.UUID;
import simulation.Exponential;
import simulation.VMTask;

/**
 *
 * @author gravena
 */
public class Main {
    public static int test_spec_id = 0;

    public static void main(String args[]) {
        ArrayList<Slave> slave = new ArrayList<>();
        ArrayList<Test> test = new ArrayList<>();                


        /*
         * Start the slave listener
         */
        //new Thread(new ConnectionListener(slave)).start();

        //slave.add(new Slave("127.0.0.1", Network.DEFAULT_PORT, "Local Machine", true));

        Scanner in = new Scanner(System.in);

        int op;
        do {
            System.out.println("\n1 - Add slave IP Address");
            System.out.println("2 - Specify a test");
            System.out.println("3 - Edit a test spec");
            System.out.println("4 - Perform a test");
            System.out.println("5 - Create a Virtual Machine");
            System.out.println("6 - Destroy a Virtual Machine");
            System.out.println("7 - Send a binary");
            System.out.println("8 - Start a test");

            op = in.nextInt();

            if (op == 1) {
                /**
                 * Register a slave
                 */
                System.out.println("Machine IP Adrress: ");
                String ip = in.next();
                System.out.println("Machine Name: ");
                String name = in.next();
                Slave new_slave = new  Slave(ip, Network.DEFAULT_PORT, name, true);
                if(Network.requestAssoc(new_slave)) {
                    slave.add(new_slave);
                } else {
                    System.out.println("Unable to associate!");
                }
                                
            } else if (op == 2) {
                /**
                 * Create a new test
                 */
                Test new_test = new Test();
                test.add(new_test);                

                System.out.println("Test name: ");
                
                String testName = in.next();
                new_test.setName(testName);
                
                System.out.println("Test '" + testName + "' created with ID: " + new_test.getId());
                System.out.println("How many stations will be added to the test?");

                int n = in.nextInt();

                int i, j;
                for (i = 0; i < n; i++) {
                    System.out.println("\nChoose the slave: ");
                    for (j = 0; j < slave.size(); j++) {
                        System.out.println(j + " - " + slave.get(j).getName());
                    }
                    int slave_id = in.nextInt();

                    System.out.println("\nChoose the virtual machine: ");

                    long checkSum_local = slave.get(slave_id).getCheckSum();
                    long checkSum_remote = Network.requestCheckSum(slave.get(slave_id));

                    if (checkSum_local != checkSum_remote) {
                        // Recebe nova lista de máquinas virtuais
                        System.err.println("Recebendo lista de máquinas virtuais...");
                        Network.getVMList(slave.get(slave_id));
                    }

                    for (j = 0; j < slave.get(slave_id).getVMSize(); j++) {
                        VirtualMachine vm = slave.get(slave_id).getVM(j);
                        if (vm.isAvailabe() && vm.isActive()) /* Checks if the VM is available for test */ {
                            System.out.println(j + " - " + vm.getName());
                        }
                    }
                    int vm_id = in.nextInt();
                    System.out.println("Enter with the lambda parameter of the exponential distribution: ");
                    double rate = in.nextDouble();
                    System.out.println("Enter the number of samples: ");
                    int samples = in.nextInt();

                    new_test.addTestSpec(new TestSpec(slave.get(slave_id), slave.get(slave_id).getVM(vm_id).getUUID(), new VMTask("test", null, new Exponential(rate),samples),new_test.getId()));
                }
            } else if (op == 3) {
            } else if (op == 4) {
                int i;
                System.out.println("Choose a test: ");
                for (i = 0; i < test.size(); i++) {
                    System.out.println(i + " - " + test.get(i).getName());
                }
                int test_id = in.nextInt();

                Network.sendTest(test.get(test_id));
            } else if (op == 5) {
                System.out.println("Choose the slave: \n");
                int i;

                for (i = 0; i < slave.size(); i++) {
                    System.out.println(i + " - " + slave.get(i).getUUID() + "(" + slave.get(i).getIp() + ")");
                }
                int slave_id = in.nextInt();

                System.out.println("Criou:" + Network.requestVMCreation(slave.get(slave_id), UUID.randomUUID(), 500));
            } else if (op == 6) {
                System.out.println("Choose the slave: \n");
                int i, j;

                for (i = 0; i < slave.size(); i++) {
                    System.out.println(i + " - " + slave.get(i).getName());
                }
                int slave_id = in.nextInt();

                long checkSum_local = slave.get(slave_id).getCheckSum();
                long checkSum_remote = Network.requestCheckSum(slave.get(slave_id));

                if (checkSum_local != checkSum_remote) {
                    // Recebe nova lista de máquinas virtuais
                    System.err.println("Recebendo lista de máquinas virtuais...");
                    Network.getVMList(slave.get(slave_id));
                }

                System.out.println("Choose the virtual machine: \n");
                for (j = 0; j < slave.get(slave_id).getVMSize(); j++) {
                    System.out.println(j + " - " + slave.get(slave_id).getVM(j).getName());
                }
                int vm_id = in.nextInt();

                System.out.println("Destruiu: " + Network.requestVMDestroy(slave.get(slave_id), slave.get(slave_id).getVM(vm_id)));
            } else if(op == 7) {
                System.out.println("Choose the slave: \n");
                int i;

                for (i = 0; i < slave.size(); i++) {
                    System.out.println(i + " - " + slave.get(i).getName());
                }
                int slave_id = in.nextInt();

                Network.sendBinary(slave.get(slave_id), "sending_test.txt");
            } else if(op == 8) {
                int i;
                System.out.println("Choose a test: ");
                for (i = 0; i < test.size(); i++) {
                    System.out.println(i + " - " + test.get(i).getName());
                }
                int test_id = in.nextInt();

                Network.startTest(test.get(test_id));
            }
        } while (op != 9);
    }
}
